/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Enlace;

import Capa_Fisica.PuertoSerial;
import java.util.ArrayDeque;
import java.util.Stack;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Daniel Gomez
 */
public class mySingleton {

    private static mySingleton instance = null;
    private boolean ready = false;
    //private Vector<Integer> mensaje = new Vector<Integer>();
    private PuertoSerial comunicacion;
    private ArrayDeque<String> tramas = new ArrayDeque<String>();
    private Vector<String> tramasR = new Vector<String>();
    public int cualVa;
    public Vector<String> bufferLlegada = new Vector<String>();

    public void setReady(boolean ready) {
        this.ready = ready;
    }

    public void setTramasR(Vector<String> tramas) {
        this.tramasR = new Vector<String>(tramas);
    }

    public boolean isReady(Vector<String > ret) {
        ret = new Vector<String>(tramasR);
        return ready;
    }

    public Vector<String> getTramas() {
        return tramasR;
    }
    
    public void getBuffer(Vector <String> v){
        v = new Vector<String>(tramas);
        return;
    }

    protected mySingleton(String port) {
        try {
            comunicacion = new PuertoSerial();
            comunicacion.connect(port);
        } catch (Exception ex) {
            Logger.getLogger(mySingleton.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static mySingleton getInstance(String port) {
        if (instance == null) {
            instance = new mySingleton(port);
        }
        return instance;
    }

    public void process(String mensajito) {
        if(tramas.isEmpty()){
            Vector<String> st = new Vector<String>();
            st.add("1111111111111111111100010000000000000000011000000000000000011111111111111111111"+"0000");
            sendTrama(st);
        }
        int numSec = Integer.parseInt(mensajito.substring(79), 2);
        mensajito = mensajito.substring(0, 79);
        System.out.println("MENSAJE -->> " + mensajito + " size " + mensajito.length() + "  T " + Util.getInstance().tipoTrama(mensajito));
        if(!Util.getInstance().isOk(mensajito)){
            System.out.print(" OK ");
            ready = true;
            tramas.clear();
            return;
        }
        if(Util.getInstance().isAcuse(mensajito)){
            if(Util.getInstance().getSecuencia(mensajito) == 8){
                if(cualVa==numSec){
                        tramas.removeFirst();
                        cualVa++;
                }
            }else{
                Vector<String> tem = new  Vector<String>(tramas);
                sendTrama(tem);
            }
                
        }
        else{
            if(Util.getInstance().verificarTrama(mensajito)){
                    tramasR.add(mensajito);
                    sendAcuse(true, numSec);
            }
            else{
                    Vector<String> v = new Vector<String>(tramas); // aca se hace el retroceso N.. enviando todas las tramas restantes
                    sendTrama(v);
            }
        }
    }

    public void sendTrama(Vector<String> vec) {
        String numSecuencia = new String();
        tramas = new ArrayDeque<String>(vec);
        ready = false;
        //vec.add("1111111111111111111101010000000000000000000000000000000000011111111111111111111");
        int i = 0;
        do {
            tramas.addLast(vec.get(i));

            System.out.println("ENVIANDO " + vec.get(i));

            /******MACHETE DE ENVIO DE SECUENCIA*******/
            numSecuencia = Integer.toBinaryString(i);
            String CerosSecuencia = new String();
            int j = 4 - numSecuencia.length();
            if (j > 0) {
                for (int l = 0; l < j; l++) {
                    CerosSecuencia += '0';
                }
            }
            //FIN MACHETE DE ENVIO DE SECUENCIA*********

            comunicacion.enviarTrama(Util.getInstance().toVector(vec.get(i) + CerosSecuencia + numSecuencia));
            i++;
        } while (i < vec.size());

    }
    private void sendAcuse(boolean b, int cual){
        ready = false;
        Trama_Acuse tr = new Trama_Acuse(b, cual);
        System.err.println("ENVIANDO ACUSE " + cual + " con boolean " + b);
        String te = tr.getTrama();
        te +="0000";
        System.out.println("xxxxxxxxxxxxxx acuse: "+te);
        comunicacion.enviarTrama(Util.getInstance().toVector(te));
    }
}
